/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
 *
 */

import { hvigorCore } from '@ohos/hvigor';
import path from 'path';

import { generateObfuscationFile, Obfuscation } from '@ohos/hvigor-arkts-compose';
import fse from 'fs-extra';

import { ApiVersion } from '../../const/sdk-const.js';
import { CodeType } from '../../enum/code-type-enum.js';
import { BuildOpt } from '../../options/build/build-opt.js';
import { getObfuscationOptionsWithCache } from '../../common/obfuscation/get-obfuscation-rules.js';
import { OhosLogger } from '../../utils/log/ohos-logger.js';
import { resolveObfuscationOptions } from '../../utils/obfuscation-config-resolver.js';
import { CompileResource } from '../compile-resource.js';
import { TargetTaskService } from '../service/target-task-service.js';
import { OhosHarTask } from '../task/ohos-har-task.js';

/**
 * 调用etsLoader生成合并的obfuscation.txt
 */
export class ProcessObfuscationFiles extends OhosHarTask {
  private _log: OhosLogger = OhosLogger.getLogger(ProcessObfuscationFiles.name);

  constructor(taskService: TargetTaskService) {
    super(taskService, { name: ProcessObfuscationFiles.name });
  }

  taskShouldDo(): boolean {
    // isObfuscatedHar为false, 且consumerRules不为空时, 调用etsLoader生成合并的obfuscation.txt
    // isObfuscatedHar为true时编译并混淆ark代码时会生成obfuscation.txt, 无需执行
    const config: Obfuscation | undefined = this.targetService.getBuildOption().arkOptions?.obfuscation;
    const etsPath = this.moduleModel.getSourceSetByTargetName(this.targetName).getCodeMap().get(CodeType.ETS)?.getSrcPath();
    return etsPath !== undefined && !this._harExtendInfo.isObfuscatedHar() && !!config?.consumerFiles && config.consumerFiles?.length > 0;
  }

  protected async doTaskAction(): Promise<void> {
    // invoke generateConsumerObConfigFile()
    if (this.compileApiVersion < ApiVersion.API_VERSION_10 || this.isFaMode) {
      return;
    }
    const buildOpt: BuildOpt = this.targetService.getBuildOption();
    if (buildOpt.debuggable) {
      return;
    }
    if (buildOpt.artifactType) {
      this._log.warn('buildOption/artifactType is deprecated, please use buildOption/arkOptions/obfuscation instead.');
    }
    const obfuscation: Obfuscation | undefined = buildOpt.arkOptions?.obfuscation;
    if (!obfuscation) {
      return;
    }
    let options;
    if (hvigorCore.getParameter().getProperty('ohos.obfuscationRules.optimization') === true) {
      try {
        options = await getObfuscationOptionsWithCache(this.targetService, obfuscation, '');
      } catch (e) {
        options = await resolveObfuscationOptions(this.targetService, obfuscation, '');
      }
    } else {
      options = await resolveObfuscationOptions(this.targetService, obfuscation, '');
    }
    if (!options) {
      return;
    }
    await fse.ensureDir(path.dirname(options.exportRulePath));
    await generateObfuscationFile(
      options,
      this.sdkInfo.getEtsLoader(),
      this.sdkInfo.getSdkVersion(),
      this.sdkInfo.getEtsComponentVersion(),
      this.isFaMode,
      this._log,
    );
  }

  initTaskDepends(): void {
    // no depends
    this.declareDepends(CompileResource.name);
  }
}
